package com.gzcsqic.excelapp.service;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import com.gzcsqic.excelapp.common.Constants;
import com.gzcsqic.excelapp.dao.*;
import com.gzcsqic.excelapp.entity.*;
import com.gzcsqic.excelapp.utils.ExcelUtil;
import com.gzcsqic.excelapp.utils.OsUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service
public class DataService {

    @Resource
    SampleMapper sampleMapper;
    @Resource
    RecordMapper recordMapper;
    @Resource
    LetterMapper letterMapper;
    @Resource
    NoticeMapper noticeMapper;
    @Resource
    FyMapper fyMapper;
    @Resource
    XcjlMapper xcjlMapper;
    @Resource
    QczpMapper qczpMapper;
    @Resource
    Bg1Mapper bg1Mapper;
    @Resource
    Bg2Mapper bg2Mapper;

    private PageData pageData;

    private List<String> excludeFieldsList = new ArrayList<>();

    public int saveToDb(PageData pageData,Integer recordId){
        // TODO 获取record记录
        Record record = recordMapper.selectByPrimaryKey(recordId);
        if(record != null){
            sampleMapper.deleteByRecordId(recordId);
            letterMapper.deleteByRecordId(recordId);
            noticeMapper.deleteByRecordId(recordId);
            fyMapper.deleteByRecordId(recordId);
            bg1Mapper.deleteByRecordId(recordId);
            bg2Mapper.deleteByRecordId(recordId);
            qczpMapper.deleteByRecordId(recordId);
            xcjlMapper.deleteByRecordId(recordId);
        }


        List<Sample> samples = pageData.getSamples();
        for (Sample sample : samples) {
            sample.setRecordId(recordId);
            sample.setTestitemJson(JSONUtil.toJsonStr(sample.getTestItem()));
        }
        // TODO

        Xcjl xcjl = pageData.getXcjl();
        xcjl.setRecordId(recordId);
        xcjl.setRecorderJson(JSONUtil.toJsonStr(xcjl.getRecorder()));
        xcjl.setDescListJson(JSONUtil.toJsonStr(xcjl.getDescList()));
        xcjl.setOperatorJson(JSONUtil.toJsonStr(xcjl.getOperator()));
        // TODO

        List<Qczp> qczp = pageData.getQczp();
        for (Qczp q : qczp) {
            q.setRecordId(recordId);
            String path = q.getPath();
            if(!StringUtils.isEmpty(path)){
                byte[] bytes = FileUtil.readBytes(path);
                q.setImgData(bytes);
            }
        }
        // TODO

        List<Fy> fys = pageData.getFys();
        for (Fy fy : fys) {
            fy.setRecordId(recordId);
        }
        // TODO

        List<Notice> notices = pageData.getNotices();
        for (Notice notice : notices) {
            notice.setRecordId(recordId);
            notice.setDescJson(JSONUtil.toJsonStr(notice.getDesc()));
        }
        // TODO

        List<Letter> letters = pageData.getLetters();
        for (Letter letter : letters) {
            letter.setRecordId(recordId);
        }
        // TODO

        List<Bg1> bg1s = pageData.getBg1s();
        if(bg1s != null && bg1s.size() > 0){
            for (Bg1 bg1 : bg1s) {
                bg1.setRecordId(recordId);
            }

        }
        // TODO

        List<Bg2> bg2s = pageData.getBg2s();
        if(bg2s != null && bg2s.size() > 0){
            for (Bg2 bg2 : bg2s) {
                bg2.setRecordId(recordId);
            }

        }

        sampleMapper.insertBatch(samples);
        letterMapper.insertBatch(letters);
        noticeMapper.insertBatch(notices);
        fyMapper.insertBatch(fys);
        bg1Mapper.insertBatch(bg1s);
        bg2Mapper.insertBatch(bg2s);
        if(qczp.size() > 0){
            qczpMapper.insertBatch(qczp);
        }
        xcjlMapper.insertSelective(xcjl);

        return 1;
    }


    public PageData readFromDb(Integer recordId){
        List<Sample> samples = sampleMapper.selectByRecordId(recordId);
        for (Sample sample : samples) {
            String testitemJson = sample.getTestitemJson();
            if(!StringUtils.isEmpty(testitemJson)){
                sample.setTestItem(JSONUtil.toList(testitemJson,String.class));
            }
        }

        List<Letter> letters = letterMapper.selectByRecordId(recordId);
        List<Notice> notices = noticeMapper.selectByRecordId(recordId);
        for (Notice notice : notices) {
            String descJson = notice.getDescJson();
            if(!StringUtils.isEmpty(descJson)){
                notice.setDesc(JSONUtil.toList(descJson,String.class));
            }
        }

        List<Fy> fies = fyMapper.selectByRecordId(recordId);
        List<Qczp> qczps = qczpMapper.selectByRecordId(recordId);
        Xcjl xcjl = xcjlMapper.selectByRecordId(recordId);
        String descListJson = xcjl.getDescListJson();
        if(!StringUtils.isEmpty(descListJson)){
            xcjl.setDescList(convert(descListJson));
        }
        String operatorJson = xcjl.getOperatorJson();
        if(!StringUtils.isEmpty(operatorJson)){
            xcjl.setOperator(JSONUtil.toList(operatorJson,String.class));
        }
        String recorderJson = xcjl.getRecorderJson();
        if(!StringUtils.isEmpty(operatorJson)){
            xcjl.setRecorder(JSONUtil.toList(recorderJson,String.class));
        }

        List<Bg1> bg1s = bg1Mapper.selectByRecordId(recordId);
        List<Bg2> bg2s = bg2Mapper.selectByRecordId(recordId);


        PageData pageData = new PageData();
        pageData.setBg1s(bg1s);
        pageData.setBg2s(bg2s);
        pageData.setXcjl(xcjl);
        pageData.setSamples(samples);
        pageData.setQczp(qczps);
        pageData.setNotices(notices);
        pageData.setLetters(letters);
        pageData.setFys(fies);
        return pageData;

    }

    private List<List<String>> convert(String json){
        List<List> lists = JSONUtil.toList(json, List.class);
        List<List<String>> result = new ArrayList<>();
        for (List list : lists) {
            List<String> item = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                item.add(String.valueOf(list.get(i)));
            }
            result.add(item);
        }
        return result;
    }

    public List<Qczp> savePic(MultipartFile[] files) throws IOException {
        List<Qczp> list = new ArrayList<>();
        String rootPath = OsUtil.getPath() + Constants.PICTEMP_DIR;
        for (MultipartFile file : files) {
            String originalFilename = file.getOriginalFilename();
            file.transferTo(new File(rootPath + originalFilename));

            String[] split = originalFilename.split("-");
            String title = split[0];
            String idx = split[1].substring(0,1);

            Qczp qczp = new Qczp();
            qczp.setTitle(title);
            qczp.setIdx(Integer.valueOf(idx));
            qczp.setPath(rootPath + originalFilename);
            list.add(qczp);
        }

        return list;
    }


    public String export(PageData pageData) {
        excludeFieldsList = Arrays.asList(Constants.excludeFeilds);
        File file = new File(OsUtil.getPath()+Constants.EXCELTEMP);
        if(file.exists()){
            file.delete();
        }

        this.pageData = pageData;
        try {
            Map<String,Object> params = new HashMap<>();
            int size = pageData.getSamples().size();

            Xcjl xcjl = pageData.getXcjl();
            if(size <= 3){
                params.putAll(covertXcjl(xcjl, 0));
            }else{
                params.putAll(covertXcjl(xcjl, 0));
                params.putAll(covertXcjl(xcjl, 1));
            }
            Map<String, Object> qczp = covertQczp(pageData.getQczp(), xcjl);
            List<Map<String, Object>> samples = convertSample(pageData.getSamples());
            List<Map<String, Object>> backUp = convertBackUp(pageData.getSamples());
            List<Map<String, Object>> fy = convertFy(pageData.getFys());
            List<Map<String, Object>> notice = convertNotice(pageData.getNotices());
            List<Map<String, Object>> bg1 = convertBg1(pageData.getBg1s());
            List<Map<String, Object>> bg2 = convertBg2(pageData.getBg2s());
            List<Map<String, Object>> letter = convertLetter(pageData.getLetters());

            for (int i = 0; i < pageData.getSamples().size(); i++) {
                params.putAll(samples.get(i));
                params.putAll(letter.get(i));
                if(fy.size() > 0){
                    params.putAll(fy.get(i));
                }
                if(notice.size() > 0){
                    params.putAll(notice.get(i));
                }
                if(bg1.size() > 0){
                    params.putAll(bg1.get(i));
                }
                if(bg2.size() > 0){
                    params.putAll(bg2.get(i));
                }
            }
            params.putAll(qczp);
            params.put("backUpList",backUp);

            String templatePath = OsUtil.getPath() + Constants.PARAM_PATH + Constants.TEMPLATE_FILE;
            Integer[] sheetIndexs = getSheetIndexs(size, templatePath);
            TemplateExportParams template = new TemplateExportParams(templatePath,sheetIndexs);
            Workbook book = ExcelExportUtil.exportExcel(template, params);
            addPic((XSSFWorkbook) book,pageData.getQczp());
            mergeCell(size,book);
            if(bg2.size() > 0){
                setUnderline(size,book);
            }
            FileOutputStream fos = new FileOutputStream(OsUtil.getPath()+Constants.EXCELTEMP);
            book.write(fos);
            fos.close();
            return OsUtil.getPath()+Constants.EXCELTEMP;
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public String exportOne(PageData pageData,int type){
        File file = new File(OsUtil.getPath()+Constants.EXCELTEMP);
        if(file.exists()){
            file.delete();
        }
        this.pageData = pageData;
        List<Integer> sheetIdxs = new ArrayList<>();
        String templatePath = OsUtil.getPath() + Constants.PARAM_PATH + Constants.TEMPLATE_FILE;
        int size = 0;
        Map<String,Object> params = new HashMap<>();
        try{
            switch (type){
                case Constants.SAMPLE:
                    List<Map<String, Object>> samples = convertSample(pageData.getSamples());
                    params.putAll(samples.get(0));
                    sheetIdxs.add(getSheetIndex("扦样单1", templatePath));
                    break;
                case Constants.XCJL:
                    Xcjl xcjl = pageData.getXcjl();
                    size = xcjl.getDescList().get(0).size()-1;
                    if(size <= 3){
                        params.putAll(covertXcjl(xcjl, 0));
                        sheetIdxs.add(getSheetIndex("现场记录单", templatePath));
                    }else{
                        params.putAll(covertXcjl(xcjl, 0));
                        params.putAll(covertXcjl(xcjl, 1));
                        sheetIdxs.add(getSheetIndex("现场记录单", templatePath));
                        sheetIdxs.add(getSheetIndex("现场记录单(2)", templatePath));
                    }
                    break;
                case Constants.LETTER:
                    List<Map<String, Object>> letter = convertLetter(pageData.getLetters());
                    params.putAll(letter.get(0));
                    sheetIdxs.add(getSheetIndex("确认函1", templatePath));
                    break;
                case Constants.QCZP:
                    Xcjl xcjl2 = pageData.getXcjl();
                    Map<String, Object> qczp = covertQczp(pageData.getQczp(), xcjl2);
                    params.putAll(qczp);
                    sheetIdxs.add(getSheetIndex("扦样照片", templatePath));
                    break;
            }


            Integer[] sheetIndexs = new Integer[sheetIdxs.size()];
            sheetIndexs = sheetIdxs.toArray(sheetIndexs);
            TemplateExportParams template = new TemplateExportParams(templatePath,sheetIndexs);
            Workbook book = ExcelExportUtil.exportExcel(template, params);
            if(Constants.QCZP == type){
                addPic((XSSFWorkbook) book,pageData.getQczp());
            }

            if(Constants.XCJL == type){
                mergeCell(size,book);
            }

            FileOutputStream fos = new FileOutputStream(OsUtil.getPath()+Constants.EXCELTEMP);
            book.write(fos);
            fos.close();
            return OsUtil.getPath()+Constants.EXCELTEMP;
        }catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }


    // 获取需要加载的sheet下标
    private Integer[] getSheetIndexs(int sampleSize,String templatePath){
        Workbook workbook = ExcelUtil.readExcelFromFile(new File(templatePath));
        List<String> names = getSheetNames(sampleSize);
        List<Integer> idx = new ArrayList<>();
        for (int i = 0; i < names.size(); i++) {
            int k = workbook.getSheetIndex(names.get(i));
            if(k >= 0){
                idx.add(k);
            }else{
                System.out.println(names.get(i));
            }
        }
        Integer[] arr = new Integer[idx.size()];
        arr = idx.toArray(arr);
        return arr;
    }

    private Integer getSheetIndex(String sheetName,String templatePath){
        Workbook workbook = ExcelUtil.readExcelFromFile(new File(templatePath));
        List<Integer> idx = new ArrayList<>();
        int k = workbook.getSheetIndex(sheetName);
        return k;
    }


    // 获取sheet名集合
    private List<String> getSheetNames(int sampleSize){
        List<String> list = new ArrayList<>();
        list.add("扦样照片");
        if(pageData.getExcludeInfoTable() == 0){
            list.add("样品信息表");
        }
        list.add("现场记录单");
        if(sampleSize > 3){
            list.add("现场记录单(2)");
        }

        for (int i = 1; i <= sampleSize; i++) {
            list.add("扦样单" + i);
            list.add("确认函" + i);
            if(pageData.getBg1s() != null){
                list.add("报告" + i + "封面");
                list.add("报告" + i + "注意事项");
                list.add("报告" + i + "第1页");
                list.add("报告" + i + "第2页");
            }
        }

        return list;

    }

    // 设置报告第2页中8行、13行C8单元格下划线
    private void setUnderline(int sampleSize,Workbook book){
        Font font = book.createFont();
        font.setUnderline(Font.U_SINGLE); //下划线
        XSSFRichTextString richString = null;

        for (int i = 0; i < sampleSize; i++) {
            Sheet sheet = book.getSheet("报告" + (i + 1) + "第2页");
            // 8行
            Row row = sheet.getRow(7);
            Cell cell = row.getCell(2);
            String value = cell.getStringCellValue();
            richString = new XSSFRichTextString(value);
            int start = value.indexOf("：") + 1;
            int end = value.indexOf("。");
            richString.applyFont(start,end,font);

            start = value.lastIndexOf("：") + 1;
            end = value.lastIndexOf("。");
            richString.applyFont(start,end,font);
            cell.setCellValue(richString);
            // 12行
            row = sheet.getRow(12);
            cell = row.getCell(3);
            value = cell.getStringCellValue();
            richString = new XSSFRichTextString(value);
            richString.applyFont(0,value.length(),font);
            cell.setCellValue(richString);

            cell = row.getCell(5);
            value = cell.getStringCellValue();
            richString = new XSSFRichTextString(value);
            richString.applyFont(0,value.length(),font);
            cell.setCellValue(richString);


            // 13行
            row = sheet.getRow(12);
            cell = row.getCell(2);
            value = cell.getStringCellValue();
            richString = new XSSFRichTextString(value);
            richString.applyFont(6,value.length()-1,font);
            cell.setCellValue(richString);
        }
    }

    // 合并现场记录部分单元格
    private void mergeCell(int sampleSize,Workbook book){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            list.add(i+9);
        }

        for (Integer i : list) {
            Sheet sheet = book.getSheet("现场记录单");
            merge(sheet, i);
            if (sampleSize > 3) {
                sheet = book.getSheet("现场记录单(2)");
                merge(sheet, i);
            }
        }


        CellRangeAddress cra = new CellRangeAddress(12, 12, 1, 2);
        Sheet sheet = book.getSheet("现场记录单");
        sheet.addMergedRegion(cra);
        if(sampleSize > 3){
            sheet = book.getSheet("现场记录单(2)");
            sheet.addMergedRegion(cra);
        }
    }

    private void setRowHeight(Row row){
        short height = row.getHeight();
        short h = (short) Math.ceil(height * 1.3);
        row.setHeight(h);
    }

    private void merge(Sheet sheet,int i){
        CellRangeAddress cra = new CellRangeAddress(i, i, 6, 8);
        Row row = sheet.getRow(i);
        CellStyle cellStyle = row.getCell(6).getCellStyle();
        Cell cell = row.getCell(7);
        if(cell == null){
            row.createCell(7).setCellStyle(cellStyle);
        }else{
            cell.setCellStyle(cellStyle);
        }

        cell = row.getCell(8);
        if(cell == null){
            row.createCell(8).setCellStyle(cellStyle);
        }else{
            cell.setCellStyle(cellStyle);
        }
        try {
            sheet.addMergedRegion(cra);
        }catch (Exception e){

        }

        if(i == 10 || i == 17 || i == 22){
            setRowHeight(row);
        }
    }

    // 备份表格数据转换
    private List<Map<String,Object>> convertBackUp(List<Sample> samples){
        List<Map<String,Object>> list = new ArrayList<>();
        for (Sample sample : samples) {
            Map<String,Object> map = new HashMap<>();
            map.put("col1",sample.getRegisteredMark());
            map.put("col2",sample.getBzDate());
            map.put("col3",sample.getExpiration());
            map.put("col4",sample.getAddress3());
            map.put("col5",sample.getCropType());
            map.put("col6",sample.getSeedType());
            map.put("col7",sample.getCropName());
            map.put("col8","");
            map.put("col9","");
            map.put("col10","");
            map.put("col11",sample.getCount());
            map.put("col12",sample.getSampleNo());
            map.put("col13",sample.getCompanyName());
            map.put("col14",sample.getProducer());
            map.put("col15","≥" + sample.getSi());
            map.put("col16","≤" + sample.getWater());
            map.put("col17","≥" + sample.getGr());
            map.put("col18","≥" + sample.getPurity());
            map.put("col19","");
            map.put("col20",sample.getWeight());
            list.add(map);
        }
        return list;
    }

    // 设置图片
    private void addPic(XSSFWorkbook book,List<Qczp> qczps) throws IOException {
        XSSFSheet sheet = book.getSheet("扦样照片");

        for (Qczp qczp : qczps) {
            Integer idx = qczp.getIdx();
            switch (idx){
                case 0:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),0,1);
                    break;
                case 1:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),6,1);
                    break;
                case 2:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),0,20);
                    break;
                case 3:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),6,20);
                    break;
                case 4:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),0,54);
                    break;
                case 5:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),6,54);
                    break;
                case 6:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),0,72);
                    break;
                case 7:
                    ExcelUtil.setPic(book,sheet,qczp.getPath(),6,72);
                    break;
            }
        }
    }

    // 样品转换
    private List<Map<String,Object>> convertSample(List<Sample> samples) throws InvocationTargetException, IllegalAccessException {
        List<Map<String,Object>> list = new ArrayList<>();

        for (int i = 0; i < samples.size(); i++) {
            Map<String,Object> param = new HashMap<>();
            Sample sample = samples.get(i);
            List<String> fieldNames = getfieldName(sample);
            fieldNames.removeAll(excludeFieldsList);
            for (String fieldName : fieldNames) {
                String key = fieldName + "-sample" + i;
                Method method = getFieldGetMethod(sample.getClass(), fieldName);
                if(fieldName.equals("testItem")){
                    List<String> vals = (List<String>) method.invoke(sample);
                    param.put(key, CollectionUtil.join(vals,"、"));
                }else if("sealed".equals(fieldName) || "gmo".equals(fieldName)){
                    String val = (String) method.invoke(sample);
                    param.put(key,"true".equals(val)?"是":"否");
                }else{
                    param.put(key,method.invoke(sample));
                }
            }
            list.add(param);
        }
        return list;
    }


    // 封页转换
    private List<Map<String,Object>> convertFy(List<Fy> fyList) throws InvocationTargetException, IllegalAccessException {
        List<Map<String,Object>> list = new ArrayList<>();
        if(fyList == null || fyList.size() == 0){
            return list;
        }
        for (int i = 0; i < fyList.size(); i++) {
            Map<String,Object> param = new HashMap<>();
            Fy fy = fyList.get(i);
            List<String> fieldNames = getfieldName(fy);
            fieldNames.removeAll(excludeFieldsList);
            for (String fieldName : fieldNames) {
                String key = fieldName + "-fy" + i;
                Method method = getFieldGetMethod(fy.getClass(), fieldName);
                String val = String.valueOf(method.invoke(fy));
//                val = StringUtils.rightPad(val,30,' ');
                param.put(key,val);
            }
            list.add(param);
        }
        return list;
    }


    // 注意事项转换
    private List<Map<String,Object>> convertNotice(List<Notice> notices) throws InvocationTargetException, IllegalAccessException {
        List<Map<String,Object>> list = new ArrayList<>();
        if(notices == null || notices.size() == 0){
            return list;
        }
        for (int i = 0; i < notices.size(); i++) {
            Map<String,Object> param = new HashMap<>();
            Notice notice = notices.get(i);
            List<String> fieldNames = getfieldName(notice);
            fieldNames.removeAll(excludeFieldsList);
            for (String fieldName : fieldNames) {
                String key = fieldName + "-notice" + i;
                Method method = getFieldGetMethod(notice.getClass(), fieldName);
                if(fieldName.equals("desc")){
                    List<String> vals = (List<String>) method.invoke(notice);
                    param.put(key, vals);
                }else{
                    param.put(key,method.invoke(notice));
                }
            }
            list.add(param);
        }
        return list;
    }

    // 报告第一页转换
    private List<Map<String,Object>> convertBg1(List<Bg1> bg1s) throws InvocationTargetException, IllegalAccessException {
        List<Map<String,Object>> list = new ArrayList<>();
        if(bg1s == null || bg1s.size() == 0){
            return list;
        }
        for (int i = 0; i < bg1s.size(); i++) {
            Map<String,Object> param = new HashMap<>();
            Bg1 bg1 = bg1s.get(i);
            List<String> fieldNames = getfieldName(bg1);
            fieldNames.removeAll(excludeFieldsList);
            for (String fieldName : fieldNames) {
                String key = fieldName + "-bg1" + i;
                Method method = getFieldGetMethod(bg1.getClass(), fieldName);
                param.put(key,method.invoke(bg1));
            }
            list.add(param);
        }
        return list;
    }

    // 报告第二页转换
    private List<Map<String,Object>> convertBg2(List<Bg2> bg2s) throws InvocationTargetException, IllegalAccessException {
        List<Map<String,Object>> list = new ArrayList<>();
        if(bg2s == null || bg2s.size() == 0){
            return list;
        }
        for (int i = 0; i < bg2s.size(); i++) {
            Map<String,Object> param = new HashMap<>();
            Bg2 bg2 = bg2s.get(i);
            List<String> fieldNames = getfieldName(bg2);
            fieldNames.removeAll(excludeFieldsList);
            for (String fieldName : fieldNames) {
                String key = fieldName + "-bg2" + i;
                Method method = getFieldGetMethod(bg2.getClass(), fieldName);
                param.put(key,method.invoke(bg2));
            }
            list.add(param);
        }
        return list;
    }

    // 确认函转换
    private List<Map<String,Object>> convertLetter(List<Letter> letters) throws InvocationTargetException, IllegalAccessException {
        List<Map<String,Object>> list = new ArrayList<>();
        for (int i = 0; i < letters.size(); i++) {
            Map<String,Object> param = new HashMap<>();
            Letter letter = letters.get(i);
            List<String> fieldNames = getfieldName(letter);
            fieldNames.removeAll(excludeFieldsList);
            for (String fieldName : fieldNames) {
                String key = fieldName + "-letter" + i;
                Method method = getFieldGetMethod(letter.getClass(), fieldName);
                param.put(key,method.invoke(letter));
            }
            list.add(param);
        }
        return list;
    }


    // 现场记录单转换
    private Map<String,Object> covertXcjl(Xcjl obj,int idx) throws  InvocationTargetException, IllegalAccessException {
        Map<String,Object> param = new HashMap<>();

        List<String> fieldNames = getfieldName(obj);
        fieldNames.removeAll(excludeFieldsList);
        for (String name : fieldNames) {
            Method method = getFieldGetMethod(obj.getClass(), name);
            String key = name + "-xcjl";
            if(name.equals("recorder") || name.equals("operator")){
                List<String> vals = (List<String>) method.invoke(obj);
                param.put(key, CollectionUtil.join(vals,"、"));
            }else if(name.equals("descList")){
                List<List<String>> datas = (List<List<String>>) method.invoke(obj);
                List<Map<String,String>> maps = new ArrayList<>();
                for (List<String> data : datas) {
                    List<String> list = null;
                    if(idx == 0){
                        list = CollectionUtil.sub(data,1,4);
                    }else{
                        list = CollectionUtil.sub(data,4,7);
                    }

                    int size = list.size();
                    for (int i = 0; i < 3 - size; i++) {
                        list.add(" ");
                    }
                    Map<String,String> map = new LinkedHashMap<>();
                    map.put("title",data.get(0));
                    map.put("col1",list.get(0));
                    map.put("col2",list.get(1));
                    map.put("col3",list.get(2));
                    maps.add(map);
                }
                if(idx == 1){
                    param.put(key + idx,maps);
                }else{
                    param.put(key,maps);
                }
            }else{
                param.put(key,  method.invoke(obj));
            }
        }
        return param;
    }


    // 扦插照片转换
    private Map<String,Object> covertQczp(List<Qczp> objs,Xcjl xcjl){
        Map<String,Object> param = new HashMap<>();
        param.put("title3","进货票据");
        param.put("title4","进货票据");
        param.put("title5","检疫证书");
        param.put("title6","农作物种子生产经营备案表");
        param.put("title7","种子销售授权委托书");
        for (Qczp obj : objs) {
            Integer idx = obj.getIdx();
            param.put("title" + idx,obj.getTitle());
        }
        param.put("date",xcjl.getDate());
        param.put("companyName",xcjl.getCompanyName());
        return param;
    }


    // 获取字段名
    public static List<String> getfieldName(Object obj){
        List<String> list = new ArrayList<>();
        Class clz =  obj.getClass();
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            list.add(field.getName());
        }
        return list;
    }


    private Method getFieldGetMethod(Class clz,String str){
        char[] chars = str.toCharArray();
        chars[0] = (char) (chars[0] - 32);
        String s = new String(chars);
        try {
            Method method = clz.getMethod("get" + s);
            return method;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//        Workbook workbook = ExcelUtil.readExcelFromFile(new File("d:/模板-扦样.xlsx"));
//        String[] names = new String[]{"扦样单1","Sheet1","报告1第1页"};
//        for (String name : names) {
//            int i = workbook.getSheetIndex(name);
//            System.out.println(i);
//        }
//
//        String s = "as";
//        System.out.println(StringUtils.rightPad(s,30,' '));

        Date d = new Date(1636400550000l);
//        Date d = new Date(1636600748000l);
        LocalDate localDate = d.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate now = LocalDate.now();
        System.out.println(ChronoUnit.DAYS.between(localDate, now));
        System.out.println(d);
        System.out.println(now);
        System.out.println(localDate);
        System.out.println(System.currentTimeMillis());

        long s = System.currentTimeMillis()/1000 - 1636400550l ;
        System.out.println(s / (24*3600));
    }

}
